﻿/**
 * @file phone.c
 *
 */

/*********************
 *      INCLUDES
 *********************/
#include <stdio.h>
#include "lv_watch.h"

#if USE_LV_WATCH_PHONE != 0

/*********************
 *      DEFINES
 *********************/
#define PHONE_RING_OFF_ANIMATION_TIME 0
#define PHONE_RING_OFF_CONTINUE_TIME 600   /*ms*/

/**********************
 *  STATIC PROTOTYPES
 **********************/
static lv_obj_t * phone_cont_create(lv_obj_t * par, lv_layout_t cont_layout, lv_style_t * style, lv_coord_t width);
static lv_obj_t * ring_off_content_create(lv_obj_t * par);
static void phone_dialing(lv_obj_t * content);
static void phone_ring(lv_obj_t * content);
static void phone_connected(lv_obj_t * content);
static void phone_left_slide_callback(lv_obj_t * obj);
static void phone_up_slide_callback(lv_obj_t * obj);
static void phone_right_slide_callback(lv_obj_t * obj);
static void dialing_animation(lv_obj_t * par);
static void ring_animation(lv_obj_t * par);
static void connected_animation(lv_obj_t * obj);
static void volume_btn_action(lv_obj_t * obj, lv_event_t e);
static void slider_event_cb(lv_obj_t * slider, lv_event_t e);
static void phone_ring_off_timeout_cb(void * para);
static void phone_obj_hide_anim_end(lv_obj_t * anim);
static void anim_fp_dialing_ring(void * obj, int32_t x);
static void anim_fp_connected(lv_anim_t * anim);
static void phone_prepare_destory(lv_obj_t * activity_obj);
static lv_obj_t * phone_get_obj(void);
static void get_time_elaps(uint32_t last_time, char * str, int8_t size);
static void call_prompt_prepare_destory(lv_obj_t * activity_obj);
static void call_prompt_ok_btn_action(lv_obj_t * btn, lv_event_t e);
static void set_volume_when_slider_act(void);

/**********************
 *  STATIC VARIABLES
**********************/
extern phone_call_params_t  call_params;
extern phone_call_params_t  call_params_wait;
#if USE_LV_WATCH_CALL_LOG
extern hal_rtc_t time_for_call_log;
#endif
bool callwait_flg = false;
bool call_double_flg = false;

/**********************
 *      MACROS
 **********************/

/**********************
 *   GLOBAL FUNCTIONS
***********************/
lv_obj_t * phone_create(lv_obj_t * activity_obj, phone_ui_t phone_ui_id)
{
    printf("%s: phone_ui_id=%d\n", __FUNCTION__, phone_ui_id);

    if(PHONE_UI_CONNECTED == phone_ui_id) {
        /* set speaker volume to nv when leaving activiry's slider */
        set_volume_when_slider_act();
    }
    /* cleanup phone first */
    phone_cleanup();

    if(activity_obj == NULL) {
        lv_watch_activity_ext_t activity_ext;
        memset(&activity_ext, 0, sizeof(lv_watch_activity_ext_t));
        activity_ext.actId = ACT_ID_PHONE;
        activity_ext.create = NULL;
        activity_ext.prepare_destory = phone_prepare_destory;
        activity_obj = lv_watch_creat_activity_obj(&activity_ext);
        LV_ASSERT_MEM(activity_obj);
        if(activity_obj == NULL) return NULL;
    }

    lv_obj_t * obj = lv_watch_obj_create(activity_obj);
    LV_ASSERT_MEM(obj);
    if(obj == NULL) return NULL;
    lv_watch_obj_set_anim_mode(obj, LV_WATCH_LEFT_OR_RIGHT_SLIDE_CALLBACK);
    lv_watch_obj_set_left_slide_cb(obj, phone_left_slide_callback);
    lv_watch_obj_set_up_slide_cb(obj,phone_up_slide_callback);
    lv_watch_obj_set_right_slide_cb(obj, phone_right_slide_callback);

    lv_phone_obj_ext_t * ext = lv_obj_allocate_ext_attr(obj, sizeof(lv_phone_obj_ext_t));
    LV_ASSERT_MEM(ext);
    if(ext == NULL) return NULL;
    ext->phone_status_label = NULL;
    ext->phone_animation_obj = NULL;
    ext->phone_ui_id = phone_ui_id;
    ext->connect_start_time = 0;
    ext->ring_off_anim_create = false;

    /* content */
    lv_obj_t * content = lv_cont_create(obj, NULL);
    lv_obj_set_size(content, lv_obj_get_width(obj), lv_obj_get_height(obj) - 20);
    lv_cont_set_layout(content, LV_LAYOUT_COLUMN_MID);
    LV_ASSERT_MEM(content);
    if(content == NULL) return NULL;
    lv_obj_add_style(content, LV_OBJ_PART_MAIN, &lv_watch_style_transp);
    /* must click false */
    lv_obj_set_click(content, false);
    lv_obj_align(content, obj, LV_ALIGN_CENTER, 0, 0);

    if(ext->phone_ui_id == PHONE_UI_DIALING) {
        phone_dialing(content);
        dialing_animation(ext->phone_status_label);
    } else if(ext->phone_ui_id == PHONE_UI_RING) {
        phone_ring(content);
        ring_animation(ext->phone_status_label);
    } else if(ext->phone_ui_id == PHONE_UI_CONNECTED) {
        phone_connected(content);
        connected_animation(ext->phone_status_label);
    }

    return obj;
}

lv_res_t phone_ring_off_create()
{
    lv_phone_obj_ext_t * ext = phone_get_ext();
    LV_ASSERT_MEM(ext);
    if(ext == NULL) return LV_RES_INV;

    if(ext->phone_ui_id == PHONE_UI_RING || ext->phone_ui_id == PHONE_UI_DIALING) {
        if(ext->phone_status_label) {
            lv_label_set_text(ext->phone_status_label, "");
        }

        ring_off_content_create(phone_get_obj());
    } else if(ext->phone_ui_id == PHONE_UI_CONNECTED) {
        ring_off_content_create(phone_get_obj());
    }

    if(ext->phone_animation_obj) {
        lv_obj_del(ext->phone_animation_obj);
        ext->phone_animation_obj = NULL;
    }

    /* set speaker volume to nv when leaving activiry's slider */
    set_volume_when_slider_act();

    /* phone cleanup when anim end*/
    if(!ext->ring_off_anim_create) {
        ext->ring_off_anim_create = true;
        lv_anim_t a;
        lv_anim_init(&a);
        lv_anim_set_var(&a, phone_get_obj());
        lv_anim_set_ready_cb(&a, (lv_anim_ready_cb_t)phone_obj_hide_anim_end);
        lv_anim_set_time(&a, PHONE_RING_OFF_CONTINUE_TIME);
        watch_wakeup_time_reset();
        lv_anim_start(&a);
    }

    return LV_RES_OK;
}

void ring_off_action(lv_obj_t * btn, lv_event_t e)
{
    (void)btn;

    if(LV_EVENT_CLICKED != e) {
        return;
    }

    if((NULL != call_params.ceer_timer_id) || (NULL != call_params.redial_timer_id)) {
        //for CME ERROR case
        printf("%s: for CME ERROR case\n", __FUNCTION__);
        watch_modem_call_response_no_carrier(-1, 0);
        return;
    }

    if(false == call_params.ring_off) {
        call_params.ring_off = true;

        if(NULL == call_params.ring_off_timer_id) {
            call_params.ring_off_timer_id = Hal_Timer_Start(RING_OFF_TIMER_LEN, phone_ring_off_timeout_cb, NULL, 0);
        }
    }

    printf("%s: state=%d\n", __FUNCTION__, call_params.state);

    switch(call_params.state) {
        case MMI_MODEM_CALL_STATE_ACTIVE:
            watch_modem_call_request_hangup_foreground_resume_background();
            break;

        case MMI_MODEM_CALL_STATE_INCOMING:
            Hal_Tone_Play_End();
            watch_modem_call_request_udub();
            break;

        default:
            watch_modem_call_request_hangup(call_params.index);
            break;
    }

#if PHONE_TEST
    watch_modem_call_response_no_carrier(call_params.index, 0);
#endif
}

lv_obj_t * call_prompt_create(lv_obj_t * activity_obj)
{
    lv_obj_t * obj;
    if(NULL == activity_obj) {
        lv_watch_activity_ext_t activity_ext;
        memset(&activity_ext, 0, sizeof(lv_watch_activity_ext_t));
        activity_ext.actId = ACT_ID_CALL_PROMPT;
        activity_ext.create = call_prompt_create;
        activity_ext.prepare_destory = call_prompt_prepare_destory;
        activity_obj = lv_watch_creat_activity_obj(&activity_ext);
        LV_ASSERT_MEM(activity_obj);
        if(NULL == activity_obj) {
            return NULL;
        }
    }

    obj = lv_watch_obj_create(activity_obj);
    LV_ASSERT_MEM(obj);
    if(NULL == obj) {
        return NULL;
    }

    lv_obj_t * cont = lv_cont_create(obj, NULL);
    lv_obj_set_size(cont, LV_HOR_RES * 5 / 6, LV_VER_RES / 2);
    lv_obj_set_pos(cont, LV_HOR_RES / 12, LV_VER_RES / 4);
    lv_obj_add_style(cont, LV_OBJ_PART_MAIN, &lv_watch_cont_opa2);

    lv_obj_t * label = lv_label_create(cont, NULL);
    lv_obj_add_style(label, LV_OBJ_PART_MAIN, &lv_watch_font20);
    lv_label_set_long_mode(label, LV_LABEL_LONG_BREAK);
    lv_label_set_align(label, LV_LABEL_ALIGN_CENTER);
    lv_obj_set_size(label, LV_HOR_RES * 5 / 6, LV_VER_RES / 2);
    lv_label_set_text_id(label, WATCH_TEXT_ID_ECALL_PROMPT_Q);

    lv_obj_t * btn = lv_btn_create(cont, NULL);
    lv_obj_set_size(btn, LV_HOR_RES * 5 / 6, LV_VER_RES / 8);
    lv_obj_set_event_cb(btn, call_prompt_ok_btn_action);
    lv_obj_align(btn, cont, LV_ALIGN_IN_BOTTOM_LEFT, 0, 0);
    lv_obj_add_protect(btn, LV_PROTECT_PRESS_LOST);

    lv_obj_t * label_btn = lv_label_create(btn, NULL);
    lv_label_set_text_id(label_btn, WATCH_TEXT_ID_OK);
    lv_obj_add_style(label, LV_OBJ_PART_MAIN, &lv_watch_font20);

    return obj;
}

void call_double_ring_off_action(lv_obj_t * btn, lv_event_t e)
{
    (void)btn;

    if(LV_EVENT_CLICKED != e) {
        return;
    }
    printf("%s\n", __FUNCTION__);
    lv_phone_obj_ext_t *ext = phone_get_ext();
    watch_modem_call_request_hangup_foreground_resume_background();
    call_double_flg = false;
    Hal_Mem_Copy(&call_params,&call_params_wait,sizeof(phone_call_params_t));
    lv_label_set_text(ext->num_label,lv_label_get_text(ext->num_label2));
    if(call_params_wait.img_src_small) {
        lv_img_set_src(ext->connect_img, call_params_wait.img_src_small);
    }
    ext->connect_start_time = ext->connect_start_time2;
    if(ext->callwait_img) {
        lv_obj_del_async(ext->callwait_img);
        ext->callwait_img = NULL;
    }
    Hal_Mem_Set(&call_params_wait,0,sizeof(phone_call_params_t));
}

void call_exchange_action(lv_obj_t * btn, lv_event_t e)
{
    if(LV_EVENT_CLICKED != e) return;
    watch_modem_call_request_switch_waiting_or_hold_and_active();
    lv_phone_obj_ext_t *ext = phone_get_ext();
    phone_call_params_t call_params_temp;
    Hal_Mem_Set(&call_params_temp, 0, sizeof(phone_call_params_t));
    Hal_Mem_Copy(&call_params_temp,&call_params,sizeof(phone_call_params_t));
    Hal_Mem_Copy(&call_params,&call_params_wait,sizeof(phone_call_params_t));
    Hal_Mem_Copy(&call_params_wait,&call_params_temp,sizeof(phone_call_params_t));
    char* txt = lv_strdup(lv_label_get_text(ext->num_label2));
    lv_label_set_text(ext->num_label2,lv_label_get_text(ext->num_label1));
    lv_label_set_text(ext->num_label1,txt);
    lv_mem_free(txt);
    char str[20] = "";
    get_time_elaps(ext->connect_start_time2, str, 20);
    uint32_t connect_start_time_temp = ext->connect_start_time;
    ext->connect_start_time = ext->connect_start_time2;
    ext->connect_start_time2 = connect_start_time_temp;
    lv_label_set_text(ext->phone_status_label1,str);
}

static void phone_call_double_connected(lv_obj_t * content)
{
    lv_phone_obj_ext_t * ext = phone_get_ext();
    LV_ASSERT_MEM(ext);
    if(ext == NULL) return;

    lv_bidi_dir_t bidi_dir = lv_obj_get_base_dir(content);

    lv_obj_t * cont_pad = phone_cont_create(content, LV_LAYOUT_OFF, &lv_watch_style_transp, lv_obj_get_width(content) - 10);
    lv_obj_t *label_pad = lv_label_create(cont_pad, NULL);
    lv_obj_add_style(label_pad, LV_OBJ_PART_MAIN, &lv_watch_font20);
    lv_label_set_text(label_pad, "");
    lv_obj_t * cont1 = phone_cont_create(content, LV_LAYOUT_OFF, &lv_watch_style_transp, lv_obj_get_width(content) - 10);
    //name and number
    lv_obj_t * label = lv_label_create(cont1, NULL);
    lv_obj_add_style(label, LV_OBJ_PART_MAIN, &lv_watch_font20);
    lv_label_set_align(label, LV_LABEL_ALIGN_CENTER);
    lv_label_set_long_mode(label, LV_LABEL_LONG_SROLL);
    lv_obj_set_width(label, lv_obj_get_width(content) - 10);
    char txt[NV_CONTACTS_MAX_NAME_LEN + NV_CONTACTS_MAX_NUMBER_LEN] = {};
    if(LV_BIDI_DIR_RTL == bidi_dir) {
        lv_obj_set_base_dir(label, LV_BIDI_DIR_LTR);
        if(!strcmp(call_params.number, PHONE_ANONYMOUS_NUMBER)) {
            strcat(txt, (const char *)lv_lang_get_text(WATCH_TEXT_ID_UNKONWN));
        } else {
            strcat(txt, call_params.number);
        }
        if(strlen(call_params.name) > 0) {
            strcat(txt, " ");
            strcat(txt, call_params.name);
        }
    } else {
        if(strlen(call_params.name) > 0) {
            strcat(txt, call_params.name);
            strcat(txt, " ");
        }
        if(!strcmp(call_params.number, PHONE_ANONYMOUS_NUMBER)) {
            strcat(txt, (const char *)lv_lang_get_text(WATCH_TEXT_ID_UNKONWN));
        } else {
            strcat(txt, call_params.number);
        }
    }
    lv_label_set_text(label, txt);
    if(LV_BIDI_DIR_RTL == bidi_dir) {
        lv_obj_align(label, cont1, LV_ALIGN_IN_TOP_RIGHT, 25, 0);
    } else {
        lv_obj_align(label, cont1, LV_ALIGN_IN_TOP_LEFT, -25, 0);
    }
    ext->num_label1 = label;

    //duration
    lv_obj_t *label_du = lv_label_create(cont1, NULL);
    lv_obj_add_style(label_du, LV_OBJ_PART_MAIN, &lv_watch_font20);
    lv_label_set_align(label_du, LV_LABEL_ALIGN_CENTER);

    lv_label_set_text(label_du, lv_label_get_text(ext->phone_status_label));
    lv_obj_set_width(label_du, lv_obj_get_width(content) - 10);
    lv_obj_set_click(label_du, false);
    lv_obj_set_base_dir(label_du, LV_BIDI_DIR_LTR);
    if(LV_BIDI_DIR_RTL == bidi_dir) {
        lv_obj_align(label_du, label, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 0);
    } else {
        lv_obj_align(label_du, label, LV_ALIGN_OUT_BOTTOM_RIGHT, 0, 0);
    }
    ext->phone_status_label1 = label_du;

    lv_obj_t * cont2 = phone_cont_create(content, LV_LAYOUT_OFF, &lv_watch_style_transp, lv_obj_get_width(content) - 10);
    //name and number
    lv_obj_t * label1 = lv_label_create(cont2, NULL);
    lv_obj_add_style(label1, LV_OBJ_PART_MAIN, &lv_watch_font20);
    lv_label_set_align(label1, LV_LABEL_ALIGN_CENTER);
    lv_label_set_long_mode(label1, LV_LABEL_LONG_SROLL);
    lv_obj_set_width(label1, lv_obj_get_width(content) - 10);
    char txt1[NV_CONTACTS_MAX_NAME_LEN + NV_CONTACTS_MAX_NUMBER_LEN] = {};
    if(LV_BIDI_DIR_RTL == bidi_dir) {
        lv_obj_set_base_dir(label1, LV_BIDI_DIR_LTR);
        strcat(txt1, call_params_wait.number);
        if(strlen(call_params_wait.name) > 0) {
            strcat(txt1, " ");
            strcat(txt1, call_params_wait.name);
        }
    } else {
        if(strlen(call_params_wait.name) > 0) {
            strcat(txt1, call_params_wait.name);
            strcat(txt1, " ");
        }
        strcat(txt1, call_params_wait.number);
    }
    lv_label_set_text(label1, txt1);
    if(LV_BIDI_DIR_RTL == bidi_dir) {
        lv_obj_align(label1, cont2, LV_ALIGN_IN_TOP_RIGHT, 25, 0);
    } else {
        lv_obj_align(label1, cont2, LV_ALIGN_IN_TOP_LEFT, -25, 0);
    }
    ext->num_label2 = label1;

    //duration
    label_du = lv_label_create(cont2, NULL);
    lv_obj_add_style(label_du, LV_OBJ_PART_MAIN, &lv_watch_font20);
    lv_label_set_align(label_du, LV_LABEL_ALIGN_CENTER);

    lv_label_set_text_id(label_du, WATCH_TEXT_ID_HOLDING);
    lv_obj_set_width(label_du, lv_obj_get_width(content) - 10);
    lv_obj_set_click(label_du, false);
    lv_obj_set_base_dir(label_du, LV_BIDI_DIR_LTR);
    if(LV_BIDI_DIR_RTL == bidi_dir) {
        lv_obj_align(label_du, label1, LV_ALIGN_OUT_BOTTOM_LEFT, -10, 0);
    } else {
        lv_obj_align(label_du, label1, LV_ALIGN_OUT_BOTTOM_RIGHT, 10, 0);
    }

    lv_obj_t * cont = phone_cont_create(content, LV_LAYOUT_OFF, &lv_watch_style_transp, lv_obj_get_width(content) - 10);

    //btn volume
    lv_obj_t * btn;
    btn = lv_imgbtn_create(cont, NULL);
    lv_imgbtn_set_src(btn, LV_BTN_STATE_RELEASED, ICON_PHONE_RING_VOLUME);
    lv_imgbtn_set_src(btn, LV_BTN_STATE_PRESSED, ICON_PHONE_RING_VOLUME);
    lv_obj_set_event_cb(btn, volume_btn_action);
    if(LV_BIDI_DIR_RTL == bidi_dir) {
        lv_obj_align(btn, cont, LV_ALIGN_IN_BOTTOM_RIGHT, 0, 0);
    } else {
        lv_obj_align(btn, cont, LV_ALIGN_IN_BOTTOM_LEFT, 0, 0);
    }

    //btn exchange
    btn = lv_btn_create(cont, NULL);
    lv_obj_add_style(btn, LV_BTN_PART_MAIN, &lv_style_transp_fit);
    lv_obj_set_style_local_bg_color(btn, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_YELLOW);
    lv_obj_set_style_local_bg_color(btn, LV_BTN_PART_MAIN, LV_STATE_PRESSED, LV_COLOR_YELLOW);
    lv_btn_set_fit2(btn, LV_FIT_NONE, LV_FIT_TIGHT);
    lv_btn_set_layout(btn, LV_LAYOUT_CENTER);
    lv_obj_set_width(btn, LV_HOR_RES / 3);
    lv_obj_set_event_cb(btn, call_exchange_action);
    lv_obj_add_protect(btn, LV_PROTECT_PRESS_LOST);

    lv_obj_t *label_option = lv_label_create(btn, NULL);
    lv_label_set_text_id(label_option, WATCH_TEXT_ID_EXCHANGE);
    lv_obj_add_style(label_option, LV_LABEL_PART_MAIN, &lv_watch_font20);
    lv_label_set_align(label_option, LV_LABEL_ALIGN_CENTER);
    lv_obj_align(btn, cont, LV_ALIGN_CENTER, 0, 0);

    //btn ring off
    btn = lv_imgbtn_create(cont, NULL);
    lv_imgbtn_set_src(btn, LV_BTN_STATE_RELEASED, ICON_PHONE_RING_OFF);
    lv_imgbtn_set_src(btn, LV_BTN_STATE_PRESSED, ICON_PHONE_RING_OFF);
    lv_obj_set_event_cb(btn, call_double_ring_off_action);
    if(LV_BIDI_DIR_RTL == bidi_dir) {
        lv_obj_align(btn, cont, LV_ALIGN_IN_BOTTOM_LEFT, 0, 0);
    } else {
        lv_obj_align(btn, cont, LV_ALIGN_IN_BOTTOM_RIGHT, 0, 0);
    }
    hal_rtc_t rtc_curr;            // current rtc time
    Hal_Rtc_Gettime(&rtc_curr);
    uint32_t connect_start_time_temp = ext->connect_start_time;
    ext->connect_start_time = time_to_seconds(&rtc_curr);
    ext->connect_start_time2 = connect_start_time_temp;
    printf("%s: connect_start_time =%u, rtc_curr = %d/%d/%d, %d:%d:%d\n", __FUNCTION__,
        ext->connect_start_time,
        rtc_curr.tm_year,
        rtc_curr.tm_mon,
        rtc_curr.tm_mday,
        rtc_curr.tm_hour,
        rtc_curr.tm_min,
        rtc_curr.tm_sec);
}

void call_wait_ring_hook_action(lv_obj_t * btn, lv_event_t e)
{
    (void)btn;

    if(LV_EVENT_CLICKED != e) {
        return;
    }
    printf("%s\n", __FUNCTION__);
    call_double_flg = true;
    watch_modem_call_request_switch_waiting_or_hold_and_active();
    lv_phone_obj_ext_t *ext = phone_get_ext();
    callwait_flg = false;
    if(ext->phone_animation_obj) {
        lv_obj_del(ext->phone_animation_obj);
        ext->phone_animation_obj = NULL;
    }
    if(ext->callwait_img) {
        lv_obj_del_async(ext->callwait_img);
        ext->callwait_img = NULL;
    }
    /* content */
    lv_obj_t * obj = phone_get_obj();
    lv_obj_t * img = lv_img_create(obj, NULL);
    lv_obj_set_size(img, LV_HOR_RES, LV_VER_RES);
    lv_obj_set_click(img, false);
    ext->callwait_img = img;
    lv_obj_t * content = lv_cont_create(img, NULL);
    lv_obj_set_size(content, LV_HOR_RES, LV_VER_RES);
    lv_cont_set_layout(content, LV_LAYOUT_COLUMN_MID);
    LV_ASSERT_MEM(content);
    if(content == NULL) return;
#ifndef USE_WATCH_LITE
    lv_img_set_src(img, watch_get_bg());
    lv_obj_add_style(content, LV_OBJ_PART_MAIN, &lv_watch_style_transp);
#else
    lv_obj_add_style(content, LV_OBJ_PART_MAIN, &lv_watch_black_tight);
    lv_obj_set_style_local_bg_color(content, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLACK);
#endif

    /* must click false */
    lv_obj_set_click(content, false);
    lv_obj_align(content, obj, LV_ALIGN_CENTER, 0, 0);
    phone_call_params_t call_params_temp;
    Hal_Mem_Set(&call_params_temp, 0, sizeof(phone_call_params_t));
    Hal_Mem_Copy(&call_params_temp,&call_params,sizeof(phone_call_params_t));
    Hal_Mem_Copy(&call_params,&call_params_wait,sizeof(phone_call_params_t));
    Hal_Mem_Copy(&call_params_wait,&call_params_temp,sizeof(phone_call_params_t));
    call_params.state      = call_params_wait.state;
#if USE_LV_WATCH_CALL_LOG
    call_log_update_call_log_info(CALL_STATUS_INCOMING, call_params.number, &time_for_call_log);
#endif
    phone_call_double_connected(content);
}

void call_wait_ring_off_action(lv_obj_t * btn, lv_event_t e)
{
    (void)btn;

    if(LV_EVENT_CLICKED != e) {
        return;
    }
    printf("%s\n", __FUNCTION__);
#if USE_LV_WATCH_CALL_LOG
    call_log_update_call_log_info(CALL_STATUS_REJECTED, call_params_wait.number, &time_for_call_log);
#endif
#if PHONE_TEST
    watch_modem_call_response_disconnect(1);
#else
    lv_phone_obj_ext_t *ext = phone_get_ext();
    watch_modem_call_request_udub();
    callwait_flg = false;
    Hal_Mem_Set(&call_params_wait, 0, sizeof(phone_call_params_t));
    if(ext->phone_animation_obj) {
        lv_obj_del(ext->phone_animation_obj);
        ext->phone_animation_obj = NULL;
    }
    if(ext->callwait_img) {
        lv_obj_del_async(ext->callwait_img);
        ext->callwait_img = NULL;
    }
#endif
}

static void phone_call_wait_ring(lv_obj_t * content)
{
    printf("%s\n", __FUNCTION__);

    lv_phone_obj_ext_t * ext = phone_get_ext();
    LV_ASSERT_MEM(ext);
    if(ext == NULL) return;
    lv_obj_t * label;

    lv_bidi_dir_t bidi_dir = lv_obj_get_base_dir(content);

    //label ringing
    label = lv_label_create(content, NULL);
    lv_obj_add_style(label, LV_OBJ_PART_MAIN, &lv_watch_font20);
    lv_label_set_align(label, LV_LABEL_ALIGN_CENTER);
    lv_label_set_text_id(label, WATCH_TEXT_ID_RINGING);
    lv_obj_set_click(label, false);
    ext->phone_wait_label = label;

    //img small
    lv_obj_t * img = lv_img_create(content, NULL);
    if(call_params_wait.img_src_small) {
        lv_img_set_src(img, call_params_wait.img_src_small);
    }

    //name and number
    label = lv_label_create(content, NULL);
    lv_obj_add_style(label, LV_OBJ_PART_MAIN, &lv_watch_font20);
    lv_label_set_align(label, LV_LABEL_ALIGN_CENTER);
    lv_label_set_long_mode(label, LV_LABEL_LONG_SROLL);
    lv_obj_set_width(label, lv_obj_get_width(content) - 10);
    char txt[NV_CONTACTS_MAX_NAME_LEN + NV_CONTACTS_MAX_NUMBER_LEN] = {};
    if(LV_BIDI_DIR_RTL == bidi_dir) {
        lv_obj_set_base_dir(label, LV_BIDI_DIR_LTR);
        strcat(txt, call_params_wait.number);
        if(strlen(call_params_wait.name) > 0) {
            strcat(txt, " ");
            strcat(txt, call_params_wait.name);
        }
    } else {
        if(strlen(call_params_wait.name) > 0) {
            strcat(txt, call_params_wait.name);
            strcat(txt, " ");
        }
        strcat(txt, call_params_wait.number);
    }
    lv_label_set_text(label, txt);

    lv_obj_t * cont = phone_cont_create(content, LV_LAYOUT_OFF, &lv_watch_style_transp, lv_obj_get_width(content) - 40);

    //btn ring off
    lv_obj_t * btn;
    btn = lv_imgbtn_create(cont, NULL);
    lv_imgbtn_set_src(btn, LV_BTN_STATE_RELEASED, ICON_PHONE_RING_OFF);
    lv_imgbtn_set_src(btn, LV_BTN_STATE_PRESSED, ICON_PHONE_RING_OFF);
    lv_obj_set_event_cb(btn, call_wait_ring_off_action);
    if(LV_BIDI_DIR_RTL == bidi_dir) {
        lv_obj_align(btn, cont, LV_ALIGN_IN_BOTTOM_RIGHT, 0, 0);
    } else {
        lv_obj_align(btn, cont, LV_ALIGN_IN_BOTTOM_LEFT, 0, 0);
    }

    //btn ring hook
    btn = lv_imgbtn_create(cont, NULL);
    lv_imgbtn_set_src(btn, LV_BTN_STATE_RELEASED, ICON_PHONE_HOOK);
    lv_imgbtn_set_src(btn, LV_BTN_STATE_PRESSED, ICON_PHONE_HOOK);
    lv_obj_set_event_cb(btn, call_wait_ring_hook_action);
    if(LV_BIDI_DIR_RTL == bidi_dir) {
        lv_obj_align(btn, cont, LV_ALIGN_IN_BOTTOM_LEFT, 0, 0);
    } else {
        lv_obj_align(btn, cont, LV_ALIGN_IN_BOTTOM_RIGHT, 0, 0);
    }
}

lv_obj_t * phone_call_waiting_create(char *number)
{
    lv_phone_obj_ext_t *ext = phone_get_ext();
    if(NULL == ext) return NULL;
    char * num_info = lv_strdup(number);
    phonebook_contact_t * contact_info = phonebook_get_contact_info(num_info);
    /* content */
    lv_obj_t * obj = phone_get_obj();
    if(NULL == obj) return NULL;
    lv_obj_t * img = lv_img_create(obj, NULL);
    lv_obj_set_size(img, LV_HOR_RES, LV_VER_RES);
    lv_obj_set_click(img, false);
    ext->callwait_img = img;
    lv_obj_t * content = lv_cont_create(img, NULL);
    lv_obj_set_size(content, LV_HOR_RES, LV_VER_RES);
    lv_cont_set_layout(content, LV_LAYOUT_COLUMN_MID);
    LV_ASSERT_MEM(content);
    if(content == NULL) return NULL;
#ifndef USE_WATCH_LITE
    lv_img_set_src(img, watch_get_bg());
    lv_obj_add_style(content, LV_OBJ_PART_MAIN, &lv_watch_style_transp);
#else
    lv_obj_add_style(content, LV_OBJ_PART_MAIN, &lv_watch_black_tight);
    lv_obj_set_style_local_bg_color(content, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLACK);
#endif
    /* must click false */
    lv_obj_set_click(content, false);
    lv_obj_align(content, obj, LV_ALIGN_CENTER, 0, 0);
    num_info = phonebook_get_phone_number(0);
    if(NULL == num_info) {    //no contact
        contact_info = (phonebook_contact_t *)Hal_Mem_Alloc(sizeof(phonebook_contact_t));
        Hal_Mem_Set(contact_info, 0, sizeof(phonebook_contact_t));
        contact_info->img_src = ICON_FAMILY;
        contact_info->img_src_small = ICON_FAMILY_SMALL;
        contact_info->contact_type = 2;
    } else {
        Hal_Mem_Free(num_info);
    }
#if PHONE_TEST
    contact_info = (phonebook_contact_t *)Hal_Mem_Alloc(sizeof(phonebook_contact_t));
    Hal_Mem_Set(contact_info, 0, sizeof(phonebook_contact_t));
    contact_info->img_src = ICON_FAMILY;
    contact_info->img_src_small = ICON_FAMILY_SMALL;
    contact_info->contact_type = 2;
#endif
    //set call params
    Hal_Mem_Set(&call_params_wait, 0, sizeof(phone_call_params_t));
    if(1 == call_params.index) {
        call_params_wait.index      = 2;
    } else {
        call_params_wait.index      = 1;
    }
    call_params_wait.is_mt      = true;
    call_params_wait.state      = MMI_MODEM_CALL_STATE_WAITING;
    call_params_wait.speaker_volume = phone_get_call_speaker_volume();
    strncpy(call_params_wait.number, number, strlen(number));
    if(NULL != contact_info) {
        Hal_Mem_Copy(call_params_wait.name, contact_info->contact_name, NV_CONTACTS_MAX_NAME_LEN);
        call_params_wait.img_src = contact_info->img_src;
        call_params_wait.img_src_small = contact_info->img_src_small;
    }
    phone_call_wait_ring(content);
    ring_animation(ext->phone_wait_label);
    return obj;
}

/**********************
 *   STATIC FUNCTIONS
 **********************/
void phone_audio_ctrl_callback(AUDIO_CTRL_PRIORITY priority)
{
    printf("%s\n", __FUNCTION__);
}

lv_obj_t * phone_get_activity_obj(void)
{
    lv_obj_t * activity_obj = lv_watch_get_activity_obj(ACT_ID_PHONE);

    return activity_obj;
}

static lv_obj_t * phone_get_obj(void)
{
    lv_obj_t * watch_obj = NULL;

    lv_obj_t * activity_obj = phone_get_activity_obj();
    if(activity_obj) {
        lv_watch_get_child_obj(activity_obj, lv_watch_obj_signal, &watch_obj);
    }

    return watch_obj;
}

lv_phone_obj_ext_t * phone_get_ext(void)
{
    lv_phone_obj_ext_t  * ext = NULL;

    lv_obj_t * watch_obj = phone_get_obj();
    if(watch_obj) {
        ext = lv_obj_get_ext_attr(watch_obj);
    }

    return ext;
}

#if PHONE_TEST
static void phone_connected_cb(void * para)
{
    watch_modem_call_response_connect(call_params.index);
}
#endif

static void phone_left_slide_callback(lv_obj_t * obj)
{
    (void)obj;
    /*when pressing, element formidden clicked, after press lost, must recover clicked.*/
    lv_watch_obj_recover_element_clicked_en(obj);

    if((MMI_MODEM_CALL_STATE_INCOMING == call_params.state)) {  //MT call
        //ring_hook_action(NULL, LV_EVENT_CLICKED);
    }
#if PHONE_TEST
    else if(MMI_MODEM_CALL_STATE_NULL == call_params.state) {   //MO call
        int32_t index = 1;

        watch_modem_call_response_originating(index);
        watch_modem_call_response_alerting(index);

        Hal_Timer_Start(60, phone_connected_cb, NULL, 0);
    }
#endif
}

static void phone_up_slide_callback(lv_obj_t * obj)
{
    (void)obj;
    /*when pressing, element formidden clicked, after press lost, must recover clicked.*/
    lv_watch_obj_recover_element_clicked_en(obj);
#if PHONE_TEST
    MMI_Modem_Call_Response_Ccwa_t *ccwa = (MMI_Modem_Call_Response_Ccwa_t *)lv_mem_alloc(sizeof(MMI_Modem_Call_Response_Ccwa_t));
    memset(ccwa,0,sizeof(MMI_Modem_Call_Response_Ccwa_t));
    ccwa->number = (char *)lv_mem_alloc(12);
    memset(ccwa->number,0,12);
    strncpy(ccwa->number,"18840902999",11);
    ccwa->type = 0;
    ccwa->class = 1;
    watch_modem_call_response_ccwa(2, ccwa);
#endif
}

static void phone_right_slide_callback(lv_obj_t * obj)
{
    (void)obj;
    /*when pressing, element formidden clicked, after press lost, must recover clicked.*/
    lv_watch_obj_recover_element_clicked_en(obj);

    //ring_off_action(NULL, LV_EVENT_CLICKED);
}

static lv_obj_t * phone_cont_create(lv_obj_t * par, lv_layout_t cont_layout, lv_style_t * style, lv_coord_t width)
{
    lv_obj_t * content = lv_cont_create(par, NULL);
    if(width > 0) {
        lv_cont_set_fit2(content, LV_FIT_NONE, LV_FIT_TIGHT);
        lv_obj_set_width(content, width);
    } else {
        lv_cont_set_fit2(content, LV_FIT_TIGHT, LV_FIT_TIGHT);
    }
    lv_obj_add_style(content, LV_OBJ_PART_MAIN, style);
    lv_cont_set_layout(content, cont_layout);
    lv_obj_set_click(content, false);
    return content;
}

static void slider_event_cb(lv_obj_t * slider, lv_event_t e)
{
    if(e == LV_EVENT_VALUE_CHANGED)
    {
        uint8_t v = lv_slider_get_value(slider);
        if(v < 1) {
            lv_slider_set_value(slider, 1, LV_ANIM_OFF);
            return;
        }
        if(!Hal_Set_BT_Audio_Path((HAL_SPEAKER_GAIN)v))
            Hal_Call_Speaker(HAL_CALL_SPK_ON, (HAL_SPEAKER_GAIN)v);
        call_params.speaker_volume = v;
    }
}

static void volume_btn_action(lv_obj_t * obj, lv_event_t e)
{
    (void)obj;

    if(LV_EVENT_CLICKED != e) {
        return;
    }
#if PHONE_TEST
    watch_modem_call_response_disconnect(1);
#else
    slider_create(NULL, SETTING_CALL_SPEAKER, 40, slider_event_cb);
#endif
}

static void phone_obj_hide_anim_end(lv_obj_t * anim)
{
    (void)anim;

    phone_cleanup();
    printf("phone_cleanup has been called in %s\n",__FUNCTION__);
}

static lv_obj_t * ring_off_content_create(lv_obj_t * par)
{
    if(par == NULL) par = lv_scr_act();

    lv_phone_obj_ext_t * ext = phone_get_ext();
    LV_ASSERT_MEM(ext);
    if(ext == NULL) return NULL;

    lv_obj_t * obj = lv_obj_create(par, NULL);
    LV_ASSERT_MEM(obj);
    if(obj == NULL) return NULL;
    lv_obj_set_size(obj, lv_obj_get_width(par), lv_obj_get_height(par));
    lv_obj_add_style(obj, LV_OBJ_PART_MAIN, &lv_style_transp_tight);

    lv_obj_t * content = lv_cont_create(obj, NULL);
    LV_ASSERT_MEM(content);
    if(content == NULL) return NULL;

    lv_obj_add_style(content, LV_OBJ_PART_MAIN, &lv_watch_cont_opa1);
    lv_obj_set_size(content, 204, 44);
    if(ext->phone_ui_id == PHONE_UI_RING || ext->phone_ui_id == PHONE_UI_DIALING) {
        lv_obj_align(content, obj, LV_ALIGN_IN_TOP_MID, 0, 10);
    } else {
        lv_obj_align(content, obj, LV_ALIGN_CENTER, 0, -12);
    }
    lv_cont_set_layout(content, LV_LAYOUT_CENTER);
    lv_obj_set_click(content, false);

    lv_obj_t * label = lv_label_create(content, NULL);
    lv_obj_add_style(label, LV_OBJ_PART_MAIN, &lv_watch_font20);
    lv_label_set_align(label, LV_LABEL_ALIGN_CENTER);

    if(ext->phone_ui_id == PHONE_UI_CONNECTED) {
        char tmp[20] = "";
        char str[30] = "";
        get_time_elaps(ext->connect_start_time, tmp, 20);
        snprintf(str, 30, "%s(%s)", (char *)lv_lang_get_text(WATCH_TEXT_ID_RING_OFF), tmp);
        lv_label_set_text(label, str);
    } else {
        lv_label_set_text_id(label, WATCH_TEXT_ID_RING_OFF);
    }
    lv_obj_set_click(label, false);

    printf("%s:ext->phone_ui_id %d\n",__FUNCTION__,ext->phone_ui_id);
    return obj;
}

static void phone_ring_off_timeout_cb(void * para)
{
    call_params.ring_off_timer_id = NULL;
    call_params.ring_off_timeout = true;
    watch_modem_call_response_no_carrier(call_params.index, 0);
}

void ring_hook_action(lv_obj_t * btn, lv_event_t e)
{
    (void)btn;

    if(LV_EVENT_CLICKED != e) {
        return;
    }

    lv_phone_obj_ext_t * ext = phone_get_ext();
    if(ext) {
        lv_obj_del(ext->btn_cont);
        char txt[NV_CONTACTS_MAX_NAME_LEN + NV_CONTACTS_MAX_NUMBER_LEN] = {};
        if(strlen(call_params.name) > 0) {
            strcat(txt, call_params.name);
            strcat(txt, " ");
        }
        strcat(txt, (char *)lv_lang_get_text(WATCH_TEXT_ID_CONNECTING));
        lv_label_set_text(ext->num_label, txt);
    }

    printf("%s\n", __FUNCTION__);

    Hal_Tone_Play_End();

    //set voice call status
    Hal_Set_Voice_Call_Status(VOICE_CALL_START);

    watch_modem_call_request_answer();

#if PHONE_TEST
    Hal_Timer_Start(60, phone_connected_cb, NULL, 0);
#endif
}

static void phone_del_slider_task(lv_task_t * task)
{
    (void)task;
    lv_obj_t * slider_activit_obj = lv_watch_get_activity_obj(ACT_ID_SLIDER);
    if(slider_activit_obj) {
        lv_obj_del(slider_activit_obj);
        printf("slider_activit_obj has been del in %s\n",__FUNCTION__);
    }
}

void phone_cleanup(void)
{
    lv_obj_t * slider_activit_obj = lv_watch_get_activity_obj(ACT_ID_SLIDER);
    if(slider_activit_obj) {
        lv_task_t * tsk = lv_task_create(phone_del_slider_task, 0, LV_TASK_PRIO_HIGH, NULL);
        lv_task_once(tsk);
    }

    lv_obj_t * activity_obj = phone_get_activity_obj();
    if(activity_obj) {
        lv_obj_del_async(activity_obj);
        printf("activity_obj has been del_async in %s\n",__FUNCTION__);
    }
}

static void anim_fp_dialing_ring(void * obj, int32_t x)
{
    if(obj != NULL) lv_obj_set_x(obj, x);
}

static void dialing_animation(lv_obj_t * par)
{
    lv_phone_obj_ext_t * ext = phone_get_ext();
    LV_ASSERT_MEM(ext);
    if(ext == NULL) return;

    lv_bidi_dir_t bidi_dir = lv_obj_get_base_dir(par);

    lv_obj_t * img = lv_img_create(phone_get_obj(), NULL);
    if(LV_BIDI_DIR_RTL == bidi_dir) {
        lv_img_set_src(img, LV_SYMBOL_LEFT);
    } else {
        lv_img_set_src(img, LV_SYMBOL_RIGHT);
    }
    lv_obj_add_style(img, LV_OBJ_PART_MAIN, &lv_watch_image);
    lv_obj_set_style_local_text_font(img, LV_IMG_PART_MAIN, LV_STATE_DEFAULT, LV_THEME_WATCH_NIGHT_SYMBOL_NORMAL);
    lv_obj_set_y(img, lv_obj_get_y(par) + lv_obj_get_y(lv_obj_get_parent(par)));
    ext->phone_animation_obj = img;

    /*Create an animation to move the button continuously left to right*/
    lv_anim_t a;
    lv_anim_path_t path;
    lv_anim_value_t start = lv_obj_get_x(par) + lv_obj_get_width(par) + 6;
    lv_anim_value_t end = start + 30;
    if(LV_BIDI_DIR_RTL == bidi_dir) {
        start = lv_obj_get_x(par) - 6 - lv_obj_get_width(img);
        end = start - 30;
    }

    lv_anim_path_init(&path);
    lv_anim_path_set_cb(&path, lv_anim_path_linear);

    lv_anim_init(&a);
    lv_anim_set_var(&a, img);
    lv_anim_set_exec_cb(&a, (lv_anim_exec_xcb_t)anim_fp_dialing_ring);
    lv_anim_set_path(&a, &path);
    lv_anim_set_values(&a, start, end);
    lv_anim_set_time(&a, 400);
    lv_anim_set_playback_time(&a, 400);
    lv_anim_set_playback_delay(&a, 0);
    lv_anim_set_repeat_count(&a, LV_ANIM_REPEAT_INFINITE);
    lv_anim_set_repeat_delay(&a, 500);

    lv_anim_start(&a);
}

static void ring_animation(lv_obj_t * par)
{
    lv_phone_obj_ext_t * ext = phone_get_ext();
    LV_ASSERT_MEM(ext);
    if(ext == NULL) return;

    lv_bidi_dir_t bidi_dir = lv_obj_get_base_dir(par);

    lv_obj_t * img = lv_img_create(phone_get_obj(), NULL);
    if(LV_BIDI_DIR_RTL == bidi_dir) {
        lv_img_set_src(img, LV_SYMBOL_RIGHT);
    } else {
        lv_img_set_src(img, LV_SYMBOL_LEFT);
    }
    lv_obj_add_style(img, LV_IMG_PART_MAIN, &lv_watch_image);
    lv_obj_set_style_local_text_font(img, LV_IMG_PART_MAIN, LV_STATE_DEFAULT, LV_THEME_WATCH_NIGHT_SYMBOL_NORMAL);
    lv_obj_set_y(img, lv_obj_get_y(par) + lv_obj_get_y(lv_obj_get_parent(par)));
    ext->phone_animation_obj = img;

    /*Create an animation to move the button continuously left to right*/
    lv_anim_t a;
    lv_anim_path_t path;
    lv_anim_value_t start = lv_obj_get_x(par) - 20;
    lv_anim_value_t end = start - 30;
    if(LV_BIDI_DIR_RTL == bidi_dir) {
        start = lv_obj_get_x(par) + lv_obj_get_width(par) + 20 - lv_obj_get_width(img);
        end = start + 30;
    }

    lv_anim_path_init(&path);
    lv_anim_path_set_cb(&path, lv_anim_path_linear);

    lv_anim_init(&a);
    lv_anim_set_var(&a, img);
    lv_anim_set_exec_cb(&a, (lv_anim_exec_xcb_t)anim_fp_dialing_ring);
    lv_anim_set_path(&a, &path);
    lv_anim_set_values(&a, start, end);
    lv_anim_set_time(&a, 400);
    lv_anim_set_playback_time(&a, 400);
    lv_anim_set_playback_delay(&a, 0);
    lv_anim_set_repeat_count(&a, LV_ANIM_REPEAT_INFINITE);
    lv_anim_set_repeat_delay(&a, 500);

    lv_anim_start(&a);
}

static void connected_animation(lv_obj_t * obj)
{
    lv_anim_t a;
    lv_anim_path_t path;

    lv_anim_path_init(&path);
    lv_anim_path_set_cb(&path, lv_anim_path_step);

    lv_anim_init(&a);
    lv_anim_set_var(&a, obj);
    lv_anim_set_start_cb(&a, (lv_anim_ready_cb_t)anim_fp_connected);
    lv_anim_set_path(&a, &path);
    lv_anim_set_time(&a, 1);
    lv_anim_set_playback_time(&a, 0);
    lv_anim_set_playback_delay(&a, 0);
    lv_anim_set_repeat_count(&a, LV_ANIM_REPEAT_INFINITE);
    lv_anim_set_repeat_delay(&a, 1000);

    lv_anim_start(&a);
}

static void anim_fp_connected(lv_anim_t * anim)
{
    lv_phone_obj_ext_t * ext = phone_get_ext();
    LV_ASSERT_MEM(ext);
    if(ext == NULL) return;

    char str[20] = "";
    get_time_elaps(ext->connect_start_time, str, 20);
    if((true!=callwait_flg)&&(true!=call_double_flg)) {
        if(anim->var) lv_label_set_text(anim->var, str);
    }
    if(callwait_flg) {
        lv_obj_set_top(lv_obj_get_parent(ext->phone_wait_label), true);
    }
    if(call_double_flg) {
        lv_obj_set_top(lv_obj_get_parent(lv_obj_get_parent(ext->num_label1)), true);
        if(ext->phone_status_label1) {
            lv_label_set_text(ext->phone_status_label1, str);
        }
    }
}

static void phone_dialing(lv_obj_t * content)
{
    printf("%s\n", __FUNCTION__);

    lv_phone_obj_ext_t * ext = phone_get_ext();
    LV_ASSERT_MEM(ext);
    if(ext == NULL) return;

    lv_bidi_dir_t bidi_dir = lv_obj_get_base_dir(content);

    //label dialing
    lv_obj_t * label = lv_label_create(content, NULL);
    lv_obj_add_style(label, LV_OBJ_PART_MAIN, &lv_watch_font20);
    lv_label_set_align(label, LV_LABEL_ALIGN_CENTER);
    lv_label_set_text_id(label, WATCH_TEXT_ID_DAILING);
    lv_obj_set_click(label, false);
    ext->phone_status_label = label;

    //img small
    lv_obj_t * img = lv_img_create(content, NULL);
    if(call_params.img_src_small) {
        lv_img_set_src(img, call_params.img_src_small);
    }

    //name and number
    label = lv_label_create(content, NULL);
    lv_obj_add_style(label, LV_OBJ_PART_MAIN, &lv_watch_font20);
    lv_label_set_align(label, LV_LABEL_ALIGN_CENTER);
    lv_label_set_long_mode(label, LV_LABEL_LONG_SROLL);
    lv_obj_set_width(label, lv_obj_get_width(content) - 10);
    char txt[NV_CONTACTS_MAX_NAME_LEN + NV_CONTACTS_MAX_NUMBER_LEN] = {};
    if(LV_BIDI_DIR_RTL == bidi_dir) {
        lv_obj_set_base_dir(label, LV_BIDI_DIR_LTR);
        if(!strcmp(call_params.number, PHONE_ANONYMOUS_NUMBER)) {
            strcat(txt, (const char *)lv_lang_get_text(WATCH_TEXT_ID_UNKONWN));
        } else {
            strcat(txt, call_params.number);
        }
        if(strlen(call_params.name) > 0) {
            strcat(txt, " ");
            strcat(txt, call_params.name);
        }
    } else {
        if(strlen(call_params.name) > 0) {
            strcat(txt, call_params.name);
            strcat(txt, " ");
        }
        if(!strcmp(call_params.number, PHONE_ANONYMOUS_NUMBER)) {
            strcat(txt, (const char *)lv_lang_get_text(WATCH_TEXT_ID_UNKONWN));
        } else {
            strcat(txt, call_params.number);
        }
    }
    lv_label_set_text(label, txt);

    lv_obj_t * cont = phone_cont_create(content, LV_LAYOUT_OFF, &lv_watch_style_transp, lv_obj_get_width(content) - 40);

    //btn volume
    lv_obj_t * btn;
    btn = lv_imgbtn_create(cont, NULL);
    lv_imgbtn_set_src(btn, LV_BTN_STATE_RELEASED, ICON_PHONE_RING_VOLUME);
    lv_imgbtn_set_src(btn, LV_BTN_STATE_PRESSED, ICON_PHONE_RING_VOLUME);
    lv_obj_set_event_cb(btn, volume_btn_action);
    if(LV_BIDI_DIR_RTL == bidi_dir) {
        lv_obj_align(btn, cont, LV_ALIGN_IN_BOTTOM_RIGHT, 0, 0);
    } else {
        lv_obj_align(btn, cont, LV_ALIGN_IN_BOTTOM_LEFT, 0, 0);
    }

    //btn ring off
    btn = lv_imgbtn_create(cont, NULL);
    lv_imgbtn_set_src(btn, LV_BTN_STATE_RELEASED, ICON_PHONE_RING_OFF);
    lv_imgbtn_set_src(btn, LV_BTN_STATE_PRESSED, ICON_PHONE_RING_OFF);
    lv_obj_set_event_cb(btn, ring_off_action);
    if(LV_BIDI_DIR_RTL == bidi_dir) {
        lv_obj_align(btn, cont, LV_ALIGN_IN_BOTTOM_LEFT, 0, 0);
    } else {
        lv_obj_align(btn, cont, LV_ALIGN_IN_BOTTOM_RIGHT, 0, 0);
    }
}

static void phone_ring(lv_obj_t * content)
{
    printf("%s\n", __FUNCTION__);

    lv_watch_indev_reset();

    lv_phone_obj_ext_t * ext = phone_get_ext();
    LV_ASSERT_MEM(ext);
    if(ext == NULL) return;
    lv_obj_t * label;

    lv_bidi_dir_t bidi_dir = lv_obj_get_base_dir(content);

    //label ringing
    label = lv_label_create(content, NULL);
    lv_obj_add_style(label, LV_OBJ_PART_MAIN, &lv_watch_font20);
    lv_label_set_align(label, LV_LABEL_ALIGN_CENTER);
    lv_label_set_text_id(label, WATCH_TEXT_ID_RINGING);
    lv_obj_set_click(label, false);
    ext->phone_status_label = label;

    //img small
    lv_obj_t * img = lv_img_create(content, NULL);
    if(call_params.img_src_small) {
        lv_img_set_src(img, call_params.img_src_small);
    }

    //name and number
    label = lv_label_create(content, NULL);
    lv_obj_add_style(label, LV_OBJ_PART_MAIN, &lv_watch_font20);
    lv_label_set_align(label, LV_LABEL_ALIGN_CENTER);
    lv_label_set_long_mode(label, LV_LABEL_LONG_SROLL);
    lv_obj_set_width(label, lv_obj_get_width(content) - 10);
    char txt[NV_CONTACTS_MAX_NAME_LEN + NV_CONTACTS_MAX_NUMBER_LEN] = {};
    if(LV_BIDI_DIR_RTL == bidi_dir) {
        lv_obj_set_base_dir(label, LV_BIDI_DIR_LTR);
        if(!strcmp(call_params.number, PHONE_ANONYMOUS_NUMBER)) {
            strcat(txt, (const char *)lv_lang_get_text(WATCH_TEXT_ID_UNKONWN));
        } else {
            strcat(txt, call_params.number);
        }
        if(strlen(call_params.name) > 0) {
            strcat(txt, " ");
            strcat(txt, call_params.name);
        }
    } else {
        if(strlen(call_params.name) > 0) {
            strcat(txt, call_params.name);
            strcat(txt, " ");
        }
        if(!strcmp(call_params.number, PHONE_ANONYMOUS_NUMBER)) {
            strcat(txt, (const char *)lv_lang_get_text(WATCH_TEXT_ID_UNKONWN));
        } else {
            strcat(txt, call_params.number);
        }
    }
    lv_label_set_text(label, txt);
    ext->num_label = label;

    lv_obj_t * cont = phone_cont_create(content, LV_LAYOUT_OFF, &lv_watch_style_transp, lv_obj_get_width(content) - 40);
    ext->btn_cont = cont;

    //btn ring off
    lv_obj_t * btn;
    btn = lv_imgbtn_create(cont, NULL);
    lv_imgbtn_set_src(btn, LV_BTN_STATE_RELEASED, ICON_PHONE_RING_OFF);
    lv_imgbtn_set_src(btn, LV_BTN_STATE_PRESSED, ICON_PHONE_RING_OFF);
    lv_obj_set_event_cb(btn, ring_off_action);
    if(LV_BIDI_DIR_RTL == bidi_dir) {
        lv_obj_align(btn, cont, LV_ALIGN_IN_BOTTOM_RIGHT, 0, 0);
    } else {
        lv_obj_align(btn, cont, LV_ALIGN_IN_BOTTOM_LEFT, 0, 0);
    }

    //btn ring hook
    btn = lv_imgbtn_create(cont, NULL);
    lv_imgbtn_set_src(btn, LV_BTN_STATE_RELEASED, ICON_PHONE_HOOK);
    lv_imgbtn_set_src(btn, LV_BTN_STATE_PRESSED, ICON_PHONE_HOOK);
    lv_obj_set_event_cb(btn, ring_hook_action);
    if(LV_BIDI_DIR_RTL == bidi_dir) {
        lv_obj_align(btn, cont, LV_ALIGN_IN_BOTTOM_LEFT, 0, 0);
    } else {
        lv_obj_align(btn, cont, LV_ALIGN_IN_BOTTOM_RIGHT, 0, 0);
    }
}

static void phone_connected(lv_obj_t * content)
{
    lv_phone_obj_ext_t * ext = phone_get_ext();
    LV_ASSERT_MEM(ext);
    if(ext == NULL) return;

    lv_bidi_dir_t bidi_dir = lv_obj_get_base_dir(content);

    //img small
    lv_obj_t * img = lv_img_create(content, NULL);
    if(call_params.img_src_small) {
        lv_img_set_src(img, call_params.img_src_small);
    }
    ext->connect_img = img;
    //name and number
    lv_obj_t * label = lv_label_create(content, NULL);
    lv_obj_add_style(label, LV_OBJ_PART_MAIN, &lv_watch_font20);
    lv_label_set_align(label, LV_LABEL_ALIGN_CENTER);
    lv_label_set_long_mode(label, LV_LABEL_LONG_SROLL);
    lv_obj_set_width(label, lv_obj_get_width(content) - 10);
    char txt[NV_CONTACTS_MAX_NAME_LEN + NV_CONTACTS_MAX_NUMBER_LEN] = {};
    if(LV_BIDI_DIR_RTL == bidi_dir) {
        lv_obj_set_base_dir(label, LV_BIDI_DIR_LTR);
        if(!strcmp(call_params.number, PHONE_ANONYMOUS_NUMBER)) {
            strcat(txt, (const char *)lv_lang_get_text(WATCH_TEXT_ID_UNKONWN));
        } else {
            strcat(txt, call_params.number);
        }
        if(strlen(call_params.name) > 0) {
            strcat(txt, " ");
            strcat(txt, call_params.name);
        }
    } else {
        if(strlen(call_params.name) > 0) {
            strcat(txt, call_params.name);
            strcat(txt, " ");
        }
        if(!strcmp(call_params.number, PHONE_ANONYMOUS_NUMBER)) {
            strcat(txt, (const char *)lv_lang_get_text(WATCH_TEXT_ID_UNKONWN));
        } else {
            strcat(txt, call_params.number);
        }
    }
    lv_label_set_text(label, txt);
    ext->num_label = label;

    //duration
    label = lv_label_create(content, NULL);
    lv_obj_add_style(label, LV_OBJ_PART_MAIN, &lv_watch_font20);
    lv_label_set_align(label, LV_LABEL_ALIGN_CENTER);
    lv_label_set_text(label, "0:0");
    lv_obj_set_click(label, false);
    lv_obj_set_base_dir(label, LV_BIDI_DIR_LTR);
    ext->phone_status_label = label;

    lv_obj_t * cont = phone_cont_create(content, LV_LAYOUT_OFF, &lv_watch_style_transp, lv_obj_get_width(content) - 40);

    //btn volume
    lv_obj_t * btn;
    btn = lv_imgbtn_create(cont, NULL);
    lv_imgbtn_set_src(btn, LV_BTN_STATE_RELEASED, ICON_PHONE_RING_VOLUME);
    lv_imgbtn_set_src(btn, LV_BTN_STATE_PRESSED, ICON_PHONE_RING_VOLUME);
    lv_obj_set_event_cb(btn, volume_btn_action);
    if(LV_BIDI_DIR_RTL == bidi_dir) {
        lv_obj_align(btn, cont, LV_ALIGN_IN_BOTTOM_RIGHT, 0, 0);
    } else {
        lv_obj_align(btn, cont, LV_ALIGN_IN_BOTTOM_LEFT, 0, 0);
    }

    //btn ring off
    btn = lv_imgbtn_create(cont, NULL);
    lv_imgbtn_set_src(btn, LV_BTN_STATE_RELEASED, ICON_PHONE_RING_OFF);
    lv_imgbtn_set_src(btn, LV_BTN_STATE_PRESSED, ICON_PHONE_RING_OFF);
    lv_obj_set_event_cb(btn, ring_off_action);
    if(LV_BIDI_DIR_RTL == bidi_dir) {
        lv_obj_align(btn, cont, LV_ALIGN_IN_BOTTOM_LEFT, 0, 0);
    } else {
        lv_obj_align(btn, cont, LV_ALIGN_IN_BOTTOM_RIGHT, 0, 0);
    }

    hal_rtc_t rtc_curr;            // current rtc time
    Hal_Rtc_Gettime(&rtc_curr);
    ext->connect_start_time = time_to_seconds(&rtc_curr);
    printf("%s: connect_start_time=%u, rtc_curr = %d/%d/%d, %d:%d:%d\n", __FUNCTION__,
        ext->connect_start_time,
        rtc_curr.tm_year,
        rtc_curr.tm_mon,
        rtc_curr.tm_mday,
        rtc_curr.tm_hour,
        rtc_curr.tm_min,
        rtc_curr.tm_sec);
}

static void phone_prepare_destory(lv_obj_t * activity_obj)
{
    printf("%s\n", __FUNCTION__);

    lv_watch_png_cache_all_free();
    lv_phone_obj_ext_t *ext = phone_get_ext();
    if(callwait_flg) {
        callwait_flg = false;
        if(ext->callwait_img) {
            lv_obj_del_async(ext->callwait_img);
            ext->callwait_img = NULL;
        }
        watch_modem_call_request_udub();
    }
    if(call_double_flg) {
        call_double_flg = false;
        Hal_Mem_Set(&call_params_wait, 0, sizeof(phone_call_params_t));
        if(ext->callwait_img) {
            lv_obj_del_async(ext->callwait_img);
            ext->callwait_img = NULL;
        }
        watch_modem_call_request_hangup_foreground_resume_background();
    }
    //stop playing tone
    Hal_Tone_Play_End();

    //ring off
    ring_off_action(NULL, LV_EVENT_CLICKED);

    //stop ring off timer
    if(NULL != call_params.ring_off_timer_id) {
        Hal_Timer_Stop(call_params.ring_off_timer_id);
        call_params.ring_off_timer_id = NULL;
    }

    Hal_Mem_Set(&call_params, 0, sizeof(phone_call_params_t));
    call_params.state = MMI_MODEM_CALL_STATE_NULL;
}

static void get_time_elaps(uint32_t last_time, char * str, int8_t size)
{
    hal_rtc_t rtc_curr;            // current rtc time
    uint32_t  second_curr = 0;     // seconds of current time
    Hal_Rtc_Gettime(&rtc_curr);
    second_curr = time_to_seconds(&rtc_curr);

    printf("%s: curr=%u, start=%u\n", __FUNCTION__, second_curr, last_time);

    uint32_t elaps = second_curr - last_time;
    uint32_t seconds = elaps % 60;
    uint32_t minutes = elaps / 60;
    uint32_t hours = minutes / 60;
    minutes = minutes % 60;

    if(hours == 0) {
        if(lv_lang_act() == LANG_CH) {
            snprintf(str, size, "%d%s:%d%s", minutes, (char *)lv_lang_get_text(WATCH_TEXT_ID_MINUTES), seconds, (char *)lv_lang_get_text(WATCH_TEXT_ID_SECONDS));
        } else {
            snprintf(str, size, "%.2d:%.2d", minutes, seconds);
        }
    } else {
        if(lv_lang_act() == LANG_CH) {
            snprintf(str, size, "%d%s:%d%s:%d%s", hours, (char *)lv_lang_get_text(WATCH_TEXT_ID_HOURS), minutes, (char *)lv_lang_get_text(WATCH_TEXT_ID_MINUTES), seconds, (char *)lv_lang_get_text(WATCH_TEXT_ID_SECONDS));
        } else {
            snprintf(str, size, "%.2d:%.2d:%.2d", hours, minutes, seconds);
        }
    }
}

static void call_prompt_prepare_destory(lv_obj_t * activity_obj)
{
    lv_watch_png_cache_all_free();
}

static void call_prompt_ok_btn_action(lv_obj_t * btn, lv_event_t e)
{
    (void)btn;

    if(LV_EVENT_CLICKED != e) {
        return;
    }

    lv_obj_t * obj = lv_obj_get_parent(lv_obj_get_parent(lv_obj_get_parent(lv_obj_get_parent(btn))));

    call_prompt_prepare_destory(obj);
    lv_obj_del(obj);
}

uint8_t phone_get_call_volume(void)
{
    return call_params.speaker_volume;
}

static void set_volume_when_slider_act(void)
{
    printf("%s\n", __FUNCTION__);
    if(lv_watch_get_activity_obj(ACT_ID_SLIDER)) {
        if(MMI_MODEM_CALL_STATE_NULL != call_params.state) {
            uint8_t volume = phone_get_call_volume();
            printf("set nv, speaker volume is %d.\n", volume);
            UI_NV_Write_Req(NV_SECTION_UI_PHONE, 0, 1, &volume);
        }
    }
}

#endif /*USE_LV_WATCH_PHONE*/
